#include "Player.h"

namespace Dicewars
{
	Player::Player(unsigned int playerNumber, PlayerType type, GLfloat r, GLfloat g, GLfloat b)
	{
		playerType = type;
		number = playerNumber;
		color = new GLfloat[4];
		cursorColor = new GLfloat[4];
		highlightColor = new GLfloat[4];
		highlightColor[0] = r;
		highlightColor[1] = g;
		highlightColor[2] = b;
		highlightColor[3] = 1.0;
	}
	
	Player::~Player()
	{
		delete[] color;
		delete[] cursorColor;
		delete[] highlightColor;
	}
	
	unsigned int Player::GetNumber()
	{
		return number;
	}
	
	GLfloat* Player::GetColor()
	{
		color[0] = highlightColor[0] * 0.75;
		color[1] = highlightColor[1] * 0.75;
		color[2] = highlightColor[2] * 0.75;
		color[3] = 1.0;	
		return color;
	}
	
	GLfloat* Player::GetCursorColor()
	{
		cursorColor[0] = highlightColor[0] * 0.2;
		cursorColor[1] = highlightColor[1] * 0.2;
		cursorColor[2] = highlightColor[2] * 0.2;
		cursorColor[3] = 1.0;	
		return cursorColor;
	}
	
	GLfloat* Player::GetHighlightColor()
	{
		return highlightColor;
	}
	
	PlayerType Player::GetPlayerType()
	{
		return playerType;
	}
	
	GameTurnResult* Player::PerformMove(BoardTile* start, BoardTile* end)
	{
		int dc = start->GetDiceCount();
		GameTurnResult* result = new GameTurnResult();
		for(int i = 0; i < dc - 1; i++)
		{
			Die* movingDie = start->PopDie();			
			const Vector3 startPosition = *(movingDie->GetModel()->GetTranslation());
			int dcEnd = end->GetDiceCount();
			float endPositionX = dcEnd%2 != 0 ? end->GetModel()->GetTranslation()->x -0.5 : end->GetModel()->GetTranslation()->x + 0.5;
			float endPositionY = end->GetModel()->GetTranslation()->y + 0.4 + ((dcEnd/2) * 0.5);
			float endPositionZ = end->GetModel()->GetTranslation()->z;
			Vector3 endPosition = Vector3(endPositionX, endPositionY, endPositionZ);
			Animation* animation = new Animation(movingDie, startPosition, endPosition, 400.0);
			result->AddToAnimationQue(animation);
			end->PushDie(movingDie);
			end->SetOwner(this, GetColor());
		}
		return result;
	}

	GameTurnResult* Player::PerformAttack(BoardTile* attackingTile, BoardTile* defendingTile)
	{
		ResetResults();
		unsigned int i;
		Player* attacker = this;
		Player* defender = defendingTile->GetOwner();
		std::srand(time(0));
		unsigned int randomNumber = 0;
		unsigned int strengthAttacker = 0;
		unsigned int strengthDefender = 0;
		GameTurnResult* result = new GameTurnResult();
		int diceCountDefender = defendingTile->GetDiceCount();
		int diceCountAttacker = attackingTile->GetDiceCount();
		float* col;
		col = attackingTile->GetOwner()->GetColor();
		attackResult.color[0] = col[0];
		attackResult.color[1] = col[1];
		attackResult.color[2] = col[2];
		col = defendingTile->GetOwner()->GetColor();
		defendResult.color[0] = col[0];
		defendResult.color[1] = col[1];
		defendResult.color[2] = col[2];
		for(i = 0; i < diceCountAttacker; i++)
		{
			randomNumber = (rand()%6)+1;
			strengthAttacker+=randomNumber;
			attackResult.dice.push_back(randomNumber);
			attackResult.strength += randomNumber;
		}
		for(i = 0; i < diceCountDefender; i++)
		{
			randomNumber = (rand()%6)+1;
			strengthDefender+=randomNumber;
			defendResult.dice.push_back(randomNumber);
			defendResult.strength += randomNumber;
		}
		if (strengthAttacker > strengthDefender)
		{
			for(int i = 0; i < diceCountDefender; i++)
			{
				result->RemoveFromScene(defendingTile->PopDie());
			}
			//merge the animations from the move result into the attack result
			GameTurnResult* moveResult = PerformMove(attackingTile, defendingTile);
			std::list<Animation*> animations = moveResult->GetAnimationQue();
			std::list<Animation*>::const_iterator animationsIterator;
			for(animationsIterator = animations.begin(); animationsIterator != animations.end(); ++animationsIterator)
			{
				result->AddToAnimationQue(*animationsIterator);
			}
			defendingTile->SetOwner(attacker, attackingTile->GetOwner()->GetColor());
		}
		else if (strengthAttacker < strengthDefender)
		{
			for(int i = diceCountAttacker; i > 1; i--)
			{
				result->RemoveFromScene(attackingTile->PopDie());
			}
		}
		else
		{
			for(int i = diceCountAttacker; i > 1; i--)
			{
				result->RemoveFromScene(attackingTile->PopDie());
			}
			for(int i = diceCountDefender; i > 1; i--)
			{
				result->RemoveFromScene(defendingTile->PopDie());
			}
		}
		return result;
	}

	GameStatus Player::GetAttackerResult() const
	{
		return attackResult;
	}

	GameStatus Player::GetDefenderResult() const
	{
		return defendResult;
	}

	void Player::ResetResults()
	{
		attackResult.dice.clear();
		attackResult.strength = 0;
		defendResult.dice.clear();
		defendResult.strength = 0;
	}
}
